import { IMultiEditViewPanelStore } from '@/core/interface/widgets/store';
import {
	MultiEditViewPanelActionType,
	IMultiEditViewPanelAbility,
	IMultiEditViewPanelController,
	IParam,
	ICtrlActionResult,
	IMultiEditViewPanelModel,
	IHttpResponse,
	IMultiEditViewPanelControllerParams,
} from '../../interface';
import MultiEditViewPanelService from '@/core/modules/ctrl-service/multi-edit-view-panel-service';
import { MDCtrlController } from './md-ctrl-controller';
import { createUUID, deepCopy, formatAppDERSPath } from '@/core/utils';
import { ControlVOBase } from '@/core/modules';

/**
 * 多表单编辑面板部件控制器
 *
 * @export
 * @class MultiEditViewPanelController
 * @extends {WidgetsController<IMultiEditViewPanelStore>}
 * @implements {IMultiEditViewPanelController}
 * @template T
 */
export class MultiEditViewPanelController
	extends MDCtrlController<
		MultiEditViewPanelActionType,
		IMultiEditViewPanelStore,
		IMultiEditViewPanelAbility
	>
	implements
		IMultiEditViewPanelController<
			IMultiEditViewPanelStore,
			IMultiEditViewPanelAbility
		>
{
	/**
	 * 多编辑视图面板
	 *
	 * @protected
	 * @type {IMultiEditViewPanelModel}
	 * @memberof MultiEditViewPanelController
	 */
	protected declare model: IMultiEditViewPanelModel;

	/**
	 * 部件服务
	 *
	 * @type {MultiEditViewPanelService<ControlVOBase>}
	 * @memberof MultiEditViewPanelController
	 */
	declare ctrlService: MultiEditViewPanelService<ControlVOBase>;

	/**
	 * 嵌入视图
	 *
	 * @private
	 * @type {string}
	 * @memberof MultiEditViewPanelController
	 */
	private embedView!: IParam;

	/**
	 * Creates an instance of MultiEditViewPanelController.
	 * @param {IMultiEditViewPanelControllerParams<MultiEditViewPanelActionType, IMultiEditViewPanelAbility>} params
	 * @memberof MultiEditViewPanelController
	 */
	public constructor(
		params: IMultiEditViewPanelControllerParams<
			MultiEditViewPanelActionType,
			IMultiEditViewPanelAbility
		>
	) {
		super(params);
		this.ctrlInit(params);
	}

	/**
	 * 处理部件初始化
	 *
	 * @protected
	 * @param { IMultiEditViewPanelControllerParams<MultiEditViewPanelActionType, IMultiEditViewPanelAbility>} params
	 * @memberof MultiEditViewPanelController
	 */
	protected processCtrlInit(
		params: IMultiEditViewPanelControllerParams<
			MultiEditViewPanelActionType,
			IMultiEditViewPanelAbility
		>
	) {
		super.processCtrlInit(params);
		this.embedView = params.embedView;
	}

	/**
	 * 加载数据
	 *
	 * @param {IParam} [opts={}]
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof MultiEditViewPanelController
	 */
	async load(opts: IParam = {}): Promise<ICtrlActionResult> {
		const { fetchAction } = this.actions;
		const { viewParams, context } = this.store;
		if (!fetchAction) {
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const arg: any = { ...opts };
		Object.assign(arg, viewParams);
		const tempContext = deepCopy(context);
		this.beforeAsyncAction('load', tempContext, arg);
		try {
			const response: IHttpResponse = await this.ctrlService.get(
				fetchAction,
				tempContext,
				{ viewParams: arg }
			);
			if (response.success) {
				this.store.data = [];
				this.handleData(response.data);
				this.emit('load', this.getData());
				this.afterAsyncAction('load', response);
				return { ok: true, data: this.getData(), rowData: response };
			}
			this.afterAsyncAction('load', response);
			return { ok: false, data: this.getData(), rowData: response };
		} catch (error: any) {
			this.afterAsyncAction('load', error);
			return { ok: false, data: this.getData(), rowData: error };
		}
	}

	/**
	 * 保存子视图
	 *
	 * @memberof MultiEditViewPanelController
	 */
	public save(opts: IParam = {}): Promise<ICtrlActionResult> {
		return new Promise((resolve: any, reject: any) => {
			const promiseArray: any = [];
			this.subAbilityCenter.forEach((item: any) => {
				if (item && item.save && item.save instanceof Function) {
					Object.assign(opts, { srfshowinfo: false });
					const promise = item.save(opts);
					promiseArray.push(promise);
				}
			});
			const { context } = this.store;
			const tempContext = deepCopy(context);
			this.beforeAsyncAction('save', tempContext, {});
			Promise.all(promiseArray)
				.then((resArray: any) => {
					const _data: any = [];
					resArray.forEach((response: any, resIndex: number) => {
						if (!response || !response.ok) {
							this.afterAsyncAction('save', response);
							return;
						}
						_data.push(response.rowData);
					});
					const result = { ok: true, rowData: _data };
					resolve(result);
					this.afterAsyncAction('save', _data);
				})
				.catch((response: any) => {
					reject(response);
					this.afterAsyncAction('save', response);
				});
		});
	}

	/**
	 * 处理添加
	 *
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof MultiEditViewPanelController
	 */
	async handleAdd(): Promise<ICtrlActionResult> {
		const { loadDraftAction } = this.actions;
		const { viewParams, context } = this.store;
		if (!loadDraftAction) {
			return { ok: false, data: this.getData(), rowData: { status: 500 } };
		}
		const tempContext = deepCopy(context);
		try {
			const response: IHttpResponse = await this.ctrlService.loadDraft(
				loadDraftAction,
				tempContext,
				{ viewParams: deepCopy(viewParams) }
			);
			if (response.success) {
				this.handleData([response.data]);
				this.emit('add', this.getData());
				return { ok: true, data: this.getData(), rowData: response };
			}
			return { ok: false, data: this.getData(), rowData: response };
		} catch (error: any) {
			return { ok: false, data: this.getData(), rowData: error };
		}
	}

	/**
	 * 处理删除
	 *
	 * @param {IParam} item
	 * @return {*}  {Promise<ICtrlActionResult>}
	 * @memberof MultiEditViewPanelController
	 */
	async handleRemove(item: IParam): Promise<ICtrlActionResult> {
		//  删除时同时删除子能力
		const abilityId = this.model.embedView + item.id;
		if (this.subAbilityCenter.has(abilityId)) {
			this.subAbilityCenter.delete(abilityId);
		}
		if (item.data.srfuf == '0') {
			const index = this.store.data.findIndex(
				(_item: IParam) => item.id === _item.id
			);
			this.store.data.splice(index, 1);
			return { ok: true, data: this.getData(), rowData: { status: 200 } };
		} else {
			const { removeAction } = this.actions;
			const { entityCodeName } = this.model;
			const { viewParams, context } = this.store;
			if (!removeAction) {
				return { ok: false, data: this.getData(), rowData: { status: 500 } };
			}
			const tempContext = deepCopy(context);
			Object.assign(tempContext, { [entityCodeName.toLowerCase()]: item.id });
			try {
				const response: IHttpResponse = await this.ctrlService.delete(
					removeAction,
					tempContext,
					{
						[entityCodeName.toLowerCase()]: item.id,
						viewParams: deepCopy(viewParams),
					}
				);
				if (response.success) {
					const index = this.store.data.findIndex(
						(_item: IParam) => item.id === _item.id
					);
					this.store.data.splice(index, 1);
					this.emit('remove', this.getData());
					return { ok: true, data: this.getData(), rowData: response };
				}
				return { ok: false, data: this.getData(), rowData: response };
			} catch (error: any) {
				return { ok: false, data: this.getData(), rowData: error };
			}
		}
	}

	/**
	 * 处理数据
	 *
	 * @private
	 * @param {IParam[]} items
	 * @return {*}  {IParam[]}
	 * @memberof MultiEditViewPanelController
	 */
	private handleData(items: IParam[]) {
		const { context, viewParams } = this.store;
		const embedViewConfig: any = App.getAppViewConfig()[this.embedView.embedViewName];
		const parameter = embedViewConfig?.parameters[0];
        const deResParameters = formatAppDERSPath(context, embedViewConfig.appDERSPaths);
		items.forEach((item: IParam) => {
			const tempItem = {
				id: item[parameter?.parameterName.toLowerCase()]
					? item[parameter.parameterName.toLowerCase()]
					: createUUID(),
				context: deepCopy(context),
				viewParams: deepCopy(viewParams),
				data: item,
			};
			deResParameters?.forEach((deResParameter: IParam) => {
				if (context[deResParameter?.parameterName.toLowerCase()]) {
					Object.assign(tempItem.context, {
						[deResParameter.parameterName.toLowerCase()]:
							context[deResParameter.parameterName.toLowerCase()],
					});
				} else if (item[deResParameter?.parameterName.toLowerCase()]) {
					Object.assign(tempItem.context, {
						[deResParameter.parameterName.toLowerCase()]:
							item[deResParameter.parameterName.toLowerCase()],
					});
				}
			});
			if (item[parameter?.parameterName.toLowerCase()]) {
				Object.assign(tempItem.context, {
					[parameter.parameterName.toLowerCase()]:
						item[parameter.parameterName.toLowerCase()],
				});
			}
			if (item[this.embedView.embedMajorPSAppDEField.toLowerCase()]) {
				Object.assign(tempItem, {
					label: item[this.embedView.embedMajorPSAppDEField.toLowerCase()],
				});
			} else if (item.srfuf == '0') {
				Object.assign(tempItem, {
					label: `${App.ts('widget.multiedit.draftnew', '草稿-新建')}`,
				});
			} else {
				Object.assign(tempItem, {
					label: App.ts(
						this.embedView.embedViewCapPSLanguageRes,
						this.embedView.embedViewCaption
					),
				});
			}
			this.store.data.push(tempItem);
		});
	}

	/**
	 * 获取部件能力
	 *
	 * @return {*}  {A}
	 * @memberof MultiEditViewPanelController
	 */
	public getAbility(): IMultiEditViewPanelAbility {
		return {
			...super.getAbility(),
			save: this.save.bind(this),
		};
	}
}
